package com.feinno.urcs.group.interop.service;

import com.feinno.urcs.group.GroupConfiguration;
import com.feinno.urcs.group.api.*;
import com.feinno.urcs.group.entity.GroupIndex;
import com.feinno.urcs.group.entity.GroupInfo;
import com.feinno.urcs.group.interop.FxDataValidateGGrpDao;
import com.feinno.urcs.group.interop.FxDataValidateGrpDao;
import com.feinno.urcs.group.interop.FxDataValidateService;
import com.feinno.urcs.group.interop.FxDataValidateUserInfoDao;
import com.feinno.urcs.group.interop.entity.DataValidateGroupBaseInfo;
import com.feinno.urcs.group.interop.entity.DataValidateGroupMemberInfo;
import com.feinno.urcs.group.interop.entity.FXCatalogIndex;
import com.feinno.urcs.types.MobileNo;
import com.feinno.util.StringUtils;
import com.google.gson.Gson;
import org.helium.framework.annotations.ServiceImplementation;
import org.helium.framework.annotations.ServiceSetter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author Li.Hongbo <lihongbo@feinno.com>
 */

@ServiceImplementation
public class FxDataValidateServiceImpl implements FxDataValidateService {
	private static final Logger LOGGER = LoggerFactory.getLogger(FxDataValidateServiceImpl.class);

	@ServiceSetter
	private GroupDao groupDao;
	@ServiceSetter
	private GroupIndexService groupIndexService;
	@ServiceSetter
	private UserGroupListDao userGroupListDao;
	@ServiceSetter
	private GroupCacheManager groupCache;
	@ServiceSetter
	private GroupService groupService;
	@ServiceSetter
	private FxDataValidateGGrpDao gGrpDao;
	@ServiceSetter
	private FxDataValidateGrpDao grpDao;
	@ServiceSetter
	private FxDataValidateUserInfoDao fxUpDao;
	@ServiceSetter
	private FXUserIndexService fxCats;
	@ServiceSetter
	private GroupListVersionCacheManager groupListVersionCacheManager;

	@Override
	public void electionAdmin(int groupId) {

		try {
			GroupIndex groupIndex = groupIndexService.getGroupById(groupId);
			if (groupIndex == null) {
				LOGGER.warn(String.format("electionAdmin groupIndex is null groupId=%s", groupId));
				return;
			}

			GroupInfo groupInfo = groupDao.getGroupInfo(groupIndex);
			if (groupInfo == null) {
				LOGGER.warn(String.format("electionAdmin groupInfo is null groupId=%s", groupId));
				return;
			}

			MobileNo admin = null;
			try {
				admin = groupInfo.getGroupAdmin();
				return;
			} catch (Exception e) {
				LOGGER.warn(String.format("GroupId=%s no admin  will  appoint one ", groupId), e);
				admin = null;
			}
			//  这么干不仅能修正讨论组 还能修正以前的脏数据,或者错误数据.
			if (admin == null) {
				//groupInfo.getGroupType() == 0 || groupInfo.getGroupType() == 4
				// 如果是0 则可能是缓存中没有清空. 如果为4则为讨论组
				admin = groupDao.appointAdmin(groupIndex);
			}

			if (admin != null) {
				userGroupListDao.updateUserGroupIdentity(admin, groupIndex, 1);
				groupCache.clearGroup(groupId);
			} else {
				//TODO   数据修复接口. 修数据吧.
			}

		} catch (Exception e) {
			LOGGER.error(String.format("electionAdmin error GroupId=%s ", groupId), e);
		}
	}

	@Override
	public void generalValidateGroup(int groupId) {

		// 查询ConversationId  GGRP_DB ,GRPDB.
		try {
			GroupIndex groupIndex = groupIndexService.getGroupById(groupId);

			DataValidateGroupBaseInfo fxGroupIndex = gGrpDao.getGroupConversationIdByGroupId(groupId);
			if (fxGroupIndex == null) {
				LOGGER.error(String.format("generalValidateGroup fxGroupIndex is null GroupId=%s", groupId));
				return;
			}
			if (!StringUtils.isNullOrEmpty(fxGroupIndex.getConversationId())) {
				LOGGER.info(String.format("groupData is Ok groupId=%s", groupId));
				return;
			}
			fxGroupIndex.setConversationId(UUID.randomUUID().toString());
			// 更新GGRPDB 数据库,  填充ConversationId
			gGrpDao.upConversationId(fxGroupIndex.getGroupId(), fxGroupIndex.getConversationId());


			// 找出群的超级管理员
			DataValidateGroupMemberInfo superAdmin = grpDao.getGroupSuperAdmin(fxGroupIndex);
			if (superAdmin == null) {
				LOGGER.error(String.format("generalValidateGroup superAdmin null groupId=%s", groupId));
				return;
			}

			// 获取群管理的手机号
			fillMobileNo(superAdmin);

			if (StringUtils.isNullOrEmpty(superAdmin.getMobileStr())) {
				LOGGER.error(String.format("generalValidateGroup Group=%s AdminUserId=%s NoMobile", fxGroupIndex.getGroupId(), superAdmin.getUserId()));
				return;
			}
			fxGroupIndex.setSuperAdminMobile(superAdmin.getMobileNo().toString());
			// 如果是选举的群管理 需要更新群管理字段, 尤其是讨论组的..
			if (superAdmin.getIdentity() != 1) {
				// 说明是通过其他方式选出来的, 需要更新两个表
				// 这里使用UserId 更新, 因为可能没有MobileNo 字段, 需要在后面填充
				grpDao.updateGroupMemberIdentityWithUserId(fxGroupIndex, superAdmin.getUserId(), 1);
				userGroupListDao.updateUserGroupIdentityWithUserId(superAdmin.getUserId(), groupIndex, 1);
			}

			// 填充creator 字段. 所以吧填充ConversationId 的逻辑放到选举管理员后面.
			grpDao.getCreator(fxGroupIndex);

			if (StringUtils.isNullOrEmpty(fxGroupIndex.getCreateMobileNo())) {
				fxGroupIndex.setCreateMobileNo(superAdmin.getMobileNo().toString());
			} else {
				try {
					MobileNo creator = MobileNo.parseFrom(fxGroupIndex.getCreateMobileNo());
					if(creator == null) {
						fxGroupIndex.setCreateMobileNo(superAdmin.getMobileNo().toString());
					}
				} catch (Exception e) {
					fxGroupIndex.setCreateMobileNo(superAdmin.getMobileNo().toString());
				}
			}

			//填充  GRP_Group 中的 ConversationId domain 等字段
			int ret = grpDao.upDomainConversationIds(GroupConfiguration.INSTANCE.getGroupDomain(), fxGroupIndex);

			LOGGER.info(String.format("generalValidateGroup upDomainConversationIds ret=%s, GroupDomain=%s, " +
					"groupConversationId=%s GroupId=%s", ret, GroupConfiguration.INSTANCE.getGroupDomain(), fxGroupIndex.getConversationId(), fxGroupIndex.getGroupId()));


			// 填充群成员的 手机号, referBy  等

			List<DataValidateGroupMemberInfo> members = grpDao.getGroupMembers(fxGroupIndex);

			List<DataValidateGroupMemberInfo> membersMobile = members.stream().map(tmpMember -> {
				try {
					tmpMember.setReferByMobileNo(superAdmin.getMobileNo());
					fillMobileNo(tmpMember);

					return tmpMember;

				} catch (Exception e) {
					LOGGER.error(String.format("fill MobileNo or ReferBy error  fxGroupIndex=%s member=%s", new Gson().toJson(fxGroupIndex), new Gson().toJson(tmpMember)), e);
					return null;
				}
			}).collect(Collectors.toList());
			grpDao.upGroupMembers(fxGroupIndex, membersMobile);

			membersMobile.forEach(m -> {

				try {
					fxUpDao.upUserGroups(m);

				} catch (Exception e) {
					LOGGER.error(String.format("  upUserGroups  error  fxGroupIndex=%s member=%s", new Gson().toJson(fxGroupIndex), new Gson().toJson(m)), e);
				}

			});
			groupCache.clearGroup(groupId);

		} catch (Exception e) {
			LOGGER.error(String.format("generalValidateGroup error groupid=%s", groupId), e);
		}


		// 查询GroupInfo . GRPDB
		// 查询MobileNo  GRP_GroupMember
		// 查询 MobileNo GRP_UserGroups


	}

	@Override
	public void loadData(MobileNo userMobileNo) {
		try {
			FXCatalogIndex fxCatalogIndex = fxCats.getFXCatalogIndex(userMobileNo);

			if (fxCatalogIndex == null) {
				LOGGER.error(String.format("getFXCatalogIndex is null MobileNo=%s", userMobileNo));
				return;
			}
			List<GroupIndex> groupIds = fxUpDao.getUserGroupList(fxCatalogIndex.getUserId(), fxCatalogIndex.getLogicalPoolId());

			LOGGER.info(String.format("UserMobile =%s UserId=%s, LogicalPool=%s groups=%s \n", userMobileNo, fxCatalogIndex.getUserId(), fxCatalogIndex.getLogicalPoolId(), new Gson().toJson(groupIds)));
			if (groupIds != null) {
				groupIds.forEach(index -> {
					generalValidateGroup(index.getGroupId());
				});
			}
			// 升级数据后，将版本号+1
			groupListVersionCacheManager.incGrpListVer(userMobileNo);
		} catch (Exception e) {
			LOGGER.error(String.format("getFXCatalogIndex error MobileNo=%s", userMobileNo), e);

		}
	}

	private void fillMobileNo(DataValidateGroupMemberInfo member) {
		try {
			fxUpDao.getUserInfo(member);
		} catch (Exception e) {
			LOGGER.error(String.format("getMobileNoByUserId index=%s", new Gson().toJson(member)), e);
		}
	}

	public static void main(String args[]) {
		String str = "<?xml version=\"1.0\" encoding=\"utf-8\"?><conference-info xmlns=\"urn:ietf:params:xml:ns:conference-info\" entity=\"sip:+8613426247167@test.ims.mnc000.mcc460.3gppnetwork.org\" state=\"list\"><conference-list><grouplist-ver version=\"5\"></grouplist-ver><grouplist></grouplist></conference-list></conference-info>";
		System.out.println(str.getBytes().length);

	}

}
